package com.sirap.spring.boot.demo.controller;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.google.common.collect.Lists;
import com.sirap.basic.tool.D;
import com.sirap.basic.util.Amaps;
import com.sirap.basic.util.DateUtil;
import com.sirap.basic.util.EmptyUtil;
import com.sirap.basic.util.FileUtil;
import com.sirap.basic.util.IOUtil;
import com.sirap.basic.util.MathUtil;
import com.sirap.basic.util.StrUtil;
import com.sirap.basic.util.XCodeUtil;
import com.sirap.fish.FishFileHelper;
import com.sirap.msoffice.MsExcelHelper;
import com.sirap.msoffice.MsWordHelper;
import com.sirap.spring.boot.demo.config.RingUtil;
import com.sirap.third.media.MediaHelper;
import com.sirap.third.msoffice.PdfHelper;

@Controller
@RequestMapping(value = "/file")
public class FileController extends BaseController {

	@RequestMapping(value = "/up_input")
	public String showUpload(HashMap<String, Object> map) {
		return "file_up_input";
	}
    
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
	public String batchupload(HttpServletRequest request, HashMap<String, Object> map) {
    	List result = uploadTextAndFiles(request);

    	if(result != null) {
    		map.put("result", result);
    	}
		
		return "file_up_result";
	}

    @RequestMapping(value = "/list", method = RequestMethod.GET)
	public String listStorage(HttpServletRequest request, HashMap<String, Object> map) {
		List<Map<String, Object>> fileitems = FishFileHelper.getNormalFilesFrom(pathOfUpload());
		map.put("issuper", isSuperUser(request));
		map.put("fileitems", fileitems);
		
		return "fileList";
    }
    
    @RequestMapping(value = "/next/{filename}")
	public String nextOf(@PathVariable String filename, HttpServletRequest request, HashMap<String, Object> map) throws Exception {
    	List<Map<String, Object>> fileitems = FishFileHelper.getNormalFilesFrom(pathOfUpload());
    	String next = null;
    	for(Map<String, Object> fileitem : fileitems) {
    		String current = fileitem.get("name") + "";
    		if(StrUtil.equals(current, filename)) {
    			next = fileitem.get("next") + "";
    		}
    	}
    	
    	return buildViewUrl(next);
    }
    
    public String buildViewUrl(String filename) {
    	if(filename != null) {
        	String encoded = XCodeUtil.urlEncodeUTF8(filename);
    		String temp = encoded.replaceAll("\\+", "%20");
        	D.pla(filename, temp, encoded);
        	String redirectTo = "/file/view/" + temp;
        	return redirect(redirectTo);
    	} else {
    		return redirect("/file/list");
    	}
    }
    
    @RequestMapping(value = "/previous/{filename}")
	public String previousOf(@PathVariable String filename, HttpServletRequest request, HashMap<String, Object> map) throws Exception {
    	List<Map<String, Object>> fileitems = FishFileHelper.getNormalFilesFrom(pathOfUpload());
    	String previous = null;
    	for(Map<String, Object> fileitem : fileitems) {
    		String current = fileitem.get("name") + "";
    		D.pl(current);
    		if(StrUtil.equals(current, filename)) {
    			previous = fileitem.get("previous") + "";
    		}
    	}
    	
    	return buildViewUrl(previous);
    }

	@RequestMapping(value = "/view/{filename}")
	public String view(@PathVariable String filename, HttpServletRequest request, HashMap<String, Object> map) throws Exception {
		D.pla(filename);
		String filepath = StrUtil.useSeparator(pathOfUpload(), filename);
		String extension = FileUtil.extensionOf(filename);
		D.pl(filepath);
		File file = FileUtil.getIfNormalFile(filepath);
		map.put("issuper", isSuperUser(request));
		if(file != null) {
			String href = StrUtil.useSeparator("/storage/albums/upload", filename);
			map.put("title", filename);
			map.put("href", href);
			map.put("filesize", FileUtil.formatSize(file.length()));
			map.put("isover100k", file.length() > 100 * 1024);
			String whenCreation = DateUtil.strOf(file.lastModified(), "yyyy-MM-dd HH:mm:ss");
			long timeagoDuration = (new Date()).getTime() - file.lastModified();
			String timeago = MathUtil.dhmsStrOfSeconds((int)(timeagoDuration/1000));
			map.put("timeago", timeago);
			map.put("prettyCreation", whenCreation);
			List lines = null;
			Integer pages = null;
			String duration = null;
			String others = null;
			if(StrUtil.isIn(extension, FileUtil.EXTENSIONS_PDF)) {
				pages = PdfHelper.pagesOf(filepath);
				lines = PdfHelper.linesOf(filepath);
			} else if(StrUtil.equals("doc", extension)) {
				lines = MsWordHelper.linesOf(filepath);
				others = "I love my wife ahxiu";
			} else if(StrUtil.equals("docx", extension)) {
				pages = MsWordHelper.pagesOf(filepath);
				lines = MsWordHelper.linesOf(filepath);
			} else if(StrUtil.equals("mp3", extension)) {
				int durationInSeconds = MediaHelper.readMp3DurationInSeconds(filepath);
				String strinfo = MathUtil.dhmsStrOfSeconds(durationInSeconds);
				duration = StrUtil.occupy("{0} ({1})", durationInSeconds, strinfo);
			} else if(StrUtil.isIn(extension, FileUtil.EXTENSIONS_EXCEL)) {
				lines = MsExcelHelper.linesOf(filepath);
				pages = MsExcelHelper.pagesOf(filepath);
			} else if(StrUtil.isIn(extension, FileUtil.EXTENSIONS_TEXT)) {
				String charset = charset();
				if(request.getParameter("switch") != null) {
					charset = charsetX();
				}
				lines = IOUtil.readLines(filepath, charset);
			} else if(StrUtil.isIn(extension, FileUtil.EXTENSIONS_IMAGE)) {
				map.put("isimage", true);
			}
			
			if(lines != null) {
				String content = byHtmlBR(lines);
				map.put("content", content);
				map.put("lines", lines.size());
				map.put("chars", content.length());
			}
			if(pages != null) {
				map.put("pages", pages);
			}
			if(duration != null) {
				map.put("duration", duration);
			}
			if(others != null) {
				map.put("others", others);
			}
		} else {
			map.put("error", "文件不存在：" + filename);
		}
		
		D.pjsp(map);
		
		return "fileDetail";
	}
	
	@RequestMapping(value = "/deleteBatch", method = RequestMethod.POST)
//	@RequiresPermissions("userInfo:del")//权限管理;
	public String deleteBatch(HttpServletRequest request, HashMap<String, Object> map) {
		D.sink("see this? delete batch");
		List<Map> infos = Lists.newArrayList();
		Map<String, Object> grand = Amaps.newHashMap();
		if(isSuperUser(request) || "".isEmpty()) {
			String[] filenames = request.getParameterValues("xfilename");
			D.pl(filenames);
			if(filenames != null) {
				for(String filename : filenames) {
					if(EmptyUtil.isNullOrEmpty(filename)) {
						continue;
					}
					Map<String, Object> info = RingUtil.deleteFile(filename, pathOfUpload());
					infos.add(info);
				}
			} else {
				grand.put("error", "未指定要删除的文件。");
			}
		} else {
			grand.put("error", "您没有权限删除文件。");
		}
		
		if(!grand.isEmpty()) {
			infos.add(grand);
		}

		map.put("result", infos);
		
		return listStorage(request, map);
	}
    
	@RequestMapping(value = "/delete/{filename}")
	public String delete(@PathVariable String filename, HttpServletRequest request, HashMap<String, Object> map) {
		List<Map> infos = Lists.newArrayList();
		if(isSuperUser(request) || "".isEmpty()) {
			Map info = RingUtil.deleteFile(filename, pathOfUpload());
			infos.add(info);
		} else {
			Map<String, Object> info = Amaps.createMap("error", "您没有权限删除文件。");
			infos.add(info);
		}

		map.put("result", infos);
		
//    	String  redirectTo = "/file/view/" + filename;
//    	return redirect(redirectTo); 
		return listStorage(request, map);
	}
    
	@RequestMapping(value = "/download/{filename}")
	public void download(@PathVariable String filename, HttpServletResponse res) throws Exception {
		String encodedName = new String(filename.getBytes(), "ISO-8859-1");
		D.pla(encodedName, filename);

		res.setHeader("content-type", "application/octet-stream");
		res.setContentType("application/octet-stream");
		res.setHeader("Content-Disposition", "attachment;filename=" + encodedName);

		D.sink("Downloading " + filename);

		String filepath = StrUtil.useSeparator(pathOfUpload(), filename);
		D.pl(filepath);
		if(FileUtil.exists(filepath)) {
			readIntoStream(res.getOutputStream(), filepath);
		}
	}
	
	@ResponseBody
	@RequestMapping(value = "/finals")
	public List uploadTextAndFiles(HttpServletRequest request) {
    	String filePath = pathOfUpload();
		FileUtil.makeDirectories(filePath);
		List<Map> infos = Lists.newArrayList();
    	RingUtil.saveTextFromRequest(request, filePath, infos);

		if(MultipartHttpServletRequest.class.isInstance(request)) {
			MultipartHttpServletRequest mrequest = (MultipartHttpServletRequest)request;
			RingUtil.saveFileFromMultipartRequest(mrequest, filePath, infos);
		}

		return infos;
	}
}
